#include <head.h>

#define MAX_CLIENTS 3000

int socketFDArr[MAX_CLIENTS];
int count = 0;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

// 把字符串IP转换成数字IP
uint32_t pton(char *ip)
{
    uint32_t nIP = 0;
    inet_pton(AF_INET, ip, &nIP);
    return nIP;
}

// 把数字IP转换成字符串IP
void numIPtoString(uint32_t ip, char *psIP, int size)
{
    inet_ntop(AF_INET, &ip, psIP, size);
}

// 广播消息给所有客户端
void broadcast_message(int sender_fd, char *message)
{
    // pthread_mutex_lock(&lock);
    for (int i = 0; i < count; i++)
    {
        if (socketFDArr[i] != sender_fd)
        {
            write(socketFDArr[i], message, strlen(message));
        }
    }
    // pthread_mutex_unlock(&lock);
}

void *thread_func(void *arg)
{
    int fd = *(int *)arg;
    char buf[1024];

    while (1)
    {
        if (0 >= read(fd, buf, sizeof(buf)))
        {
            close(fd);
            // pthread_mutex_lock(&lock);
            for (int i = 0; i < count; i++)
            {
                if (socketFDArr[i] == fd)
                {
                    socketFDArr[i] = socketFDArr[count - 1];
                    count--;
                    break;
                }
            }
            //  pthread_mutex_unlock(&lock);
            return NULL;
        }
        printf("接收到的数据是:%s\n", buf);
        broadcast_message(fd, buf);
    }
}

int main(int argc, char const *argv[])
{
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    if (fd == -1)
    {
        perror("socket");
        return -1;
    }
    struct sockaddr_in addr;
    addr.sin_addr.s_addr = pton("192.168.70.37");
    addr.sin_port = htons(5000);
    addr.sin_family = AF_INET;

    int val = 1; // 1代表打开地址重复利用功能，0代表关闭
    // SOL_SOCKET是通用socket设置的意思
    // SO_REUSEADDR是地址重复利用的意思
    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
    
    if (-1 == bind(fd, (struct sockaddr *)&addr, sizeof(addr)))
    {
        perror("bind");
        close(fd);
        return -1;
    }
    if (-1 == listen(fd, 5))
    {
        perror("listen");
        close(fd);
        return -1;
    }

    struct sockaddr_in clientAddr;
    socklen_t len = sizeof(clientAddr);

    while (1)
    {
        int newSocketFd = accept(fd, (struct sockaddr *)&clientAddr, &len);
        if (-1 == newSocketFd)
        {
            perror("accept");
            continue;
        }
        // pthread_mutex_lock(&lock);
        socketFDArr[count] = newSocketFd;
        count++;
        //   pthread_mutex_unlock(&lock);

        pthread_t tid;
        pthread_create(&tid, NULL, thread_func, &socketFDArr[count - 1]);
        pthread_detach(tid);

        char szIP[16];
        numIPtoString(clientAddr.sin_addr.s_addr, szIP, sizeof(szIP));
        printf("接收到了新的链接。\n接收的套接字是:%d 接收的ip:%s, 接收到的端口:%u\n", newSocketFd, szIP, ntohs(clientAddr.sin_port));
    }
    close(fd);
    return 0;
}